package service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ListModel;

public class AcochambratedEncoderDecoder {

	public static void encode(String fieldId, Object value,
			Map<String, Object> returnMap) {
		Object[] arrayList = null;
		String prefix = ";";
		boolean model = false;
		if (value.getClass().isArray())
			arrayList = (Object[]) value;
		else if (Collection.class.isAssignableFrom(value.getClass()))
			arrayList = ((Collection<Object>) value).toArray();
		else if (ListModel.class.isAssignableFrom(value.getClass())) {
			arrayList = new Object[((ListModel) value).getSize()];
			model = true;
			for (int i = 0; i < ((ListModel) value).getSize(); i++)
				arrayList[i] = ((ListModel) value).getElementAt(i);
		}
		if (arrayList == null)
			return;
		if (model)
			prefix = "model;";
		for (int i = 0; i < arrayList.length; i++) {

			returnMap.put(fieldId + ";" + prefix + i, arrayList[i].toString());
		}

	}

	public static boolean checkIfFieldIsArray(Object value) {
		return value != null
				&& (Collection.class.isAssignableFrom(value.getClass())
						|| value.getClass().isArray() || ListModel.class
						.isAssignableFrom(value.getClass()));
	}

	public static Map<String, Object> decodeMap(Map<String, Object> returnMap) {
		List<String> keysToBeDecoded = new ArrayList<String>();
		for (String s : returnMap.keySet())
			if (s.split(";").length > 1)
				keysToBeDecoded.add(s);
		Collections.sort(keysToBeDecoded);
		Map<String,Object> newEntries = generateNewEntries(returnMap, keysToBeDecoded);
		deleteOldEntries (returnMap,keysToBeDecoded);
		addNewEntries (returnMap,newEntries);
		return returnMap;
	}

	private static void addNewEntries(Map<String, Object> returnMap,
			Map<String, Object> newEntries) {
		returnMap.putAll(newEntries);
	}

	private static void deleteOldEntries(Map<String, Object> returnMap,
			List<String> keysToBeDecoded) {
		for (String s: keysToBeDecoded)
			returnMap.remove(s);
	}

	private static Map<String, Object> generateNewEntries(Map<String, Object> returnMap,
			List<String> keysToBeDecoded) {
		Object currentObject = null;
		String currentKey = "";
		HashMap<String, Object> objectsToBeAdded = new HashMap<String, Object>();
		for (String element : keysToBeDecoded) {
			if (!element.split(";")[0].equals(currentKey)) {
				if (currentObject != null)
					objectsToBeAdded.put(currentKey, currentObject);
				currentKey = element.split(";")[0];
				currentObject=createNewElement(element, currentObject);
				addToPreviouslyCreatedElement(element, currentObject, returnMap
						.get(element));
			} else
				addToPreviouslyCreatedElement(element, currentObject, returnMap
						.get(element));
		}
		objectsToBeAdded.put(currentKey, currentObject);
		return objectsToBeAdded;
	}

	private static void addToPreviouslyCreatedElement(String element,
			Object currentObject, Object object) {
		if (Collection.class.isAssignableFrom(currentObject.getClass()))
			((List<Object>) currentObject).add(object);
		else if (ListModel.class.isAssignableFrom(currentObject.getClass()))
			((DefaultComboBoxModel) currentObject).addElement(object);

	}

	private static Object createNewElement(String element, Object currentObject) {
		if (element.split(";")[1].equals("model"))
			currentObject = new DefaultComboBoxModel();
		else
			currentObject = new ArrayList<Object>();
		return currentObject;
	
	}

}
